#pragma once
#include <iostream>
#include <unordered_map>
#include <list>

using namespace std;

class LRUCache {
public:
    LRUCache(int capacity) 
    :_capacity(capacity)
    {
        
    }
    
    int get(int key) {
        //判断key是否存在
        auto ret=_hash.find(key);
        if(ret!=_hash.end())
        {
            //把key对应的节点挪到链表的头部
            LtIter it=ret->second;  //找到它的节点--hash表实现O(1)出查找
            //转移节点
            _LURlist.splice(_LURlist.begin(),_LURlist,it);

            return it->second;
        }

        return -1;
    }
    
    void put(int key, int value) 
    {
        //判断是更新还是新增
        auto ret=_hash.find(key);
        if(ret==_hash.end())
        {
            //新增
            //判断是否满了，满了要删除最近最少使用的数据
            if(_capacity==_hash.size())
            {
                //删除LRU的数据
                pair<int,int> back=_LURlist.back();
                _hash.erase(back.first);
                _LURlist.pop_back();
            }

            //没满
            _LURlist.push_front(make_pair(key,value));
            _hash[key]=_LURlist.begin();
        }
        else
        //更新
        {
            LtIter it=ret->second;  //找到它的节点--hash表实现O(1)出查找
            it->second=value;
            //转移节点
            _LURlist.splice(_LURlist.begin(),_LURlist,it);
        }
        
    }
private:
    size_t _capacity;
    typedef list<pair<int,int>>::iterator LtIter;
    unordered_map<int,LtIter> _hash;
    list<pair<int,int>> _LURlist;
};